#!/usr/bin/python
# -*- coding: utf-8 -*-
# Project : flacon
# File : flacon.py
# (c) Alexander Sokolov sokoloff.a@gmail.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

import os
import inspect
import sys
import unittest

from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import *

QSettings.setPath(QSettings.IniFormat,    QSettings.UserScope, "/tmp")
QSettings.setPath(QSettings.NativeFormat, QSettings.UserScope, "/tmp")


sys.path.append(os.path.dirname(__file__) + "/..")

import flacon
import track
import trackset
from disc import *
import cuecreator
import settings


#*******************************************************************
#
#*******************************************************************
def dataDir():
    return os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + "/data/"



class cueCreatorTest2(unittest.TestCase):

   #****************************************************************
   #
   #****************************************************************
    def setUp(self):
        self._disc = Disc()
        self._inputFile = ""
        self._pregapFile = ""
        self._title = ""
        self._expectedFile = ""


   #****************************************************************
   #
   #****************************************************************
    def setTitle(self, cueFile):
        self.title = ""

   #****************************************************************
   #
   #****************************************************************
    def setInputCueFile(self, cueFile):
        self._inputFile = cueFile
        tracks = trackset.CueTrackSet(dataDir() + cueFile)
        self._disc.addTrackSet(tracks)
        tracks.activate()


   #****************************************************************
   #
   #****************************************************************
    def setExpectedFile(self, file):
        self.expectedFile = file


   #****************************************************************
   #
   #****************************************************************
    def setPregapFile(self, pregapFileName):
        self._pregapFile = pregapFileName


   #****************************************************************
   #
   #****************************************************************
    def prepareExpectedCUE(self, cueFile):
        inFile  = open(cueFile, 'r')
        outFileName = "/tmp/" + os.path.basename(cueFile)
        outFile = open(outFileName, 'w')
        for l in inFile.readlines():
            l = l.replace('%FLACON_VERSION%', flacon.FLACON_VERSION)
            outFile.write(l)

        return outFileName


   #****************************************************************
   #
   #****************************************************************
    def test(self):
        if self.__class__.__name__ == "cueCreatorTest2":
            return

        outCueFile = "/tmp/" + os.path.basename(self._inputFile)

        cue = cuecreator.CueCreator(self._disc)
        cue.setPregapFileName(self._pregapFile)
        cue.write(outCueFile)

        res = open(outCueFile, 'r').read()
        expFile = self.prepareExpectedCUE(dataDir() + self.expectedFile)
        exp= open(expFile, 'r').read()
        s = "%s\nThe result is different from the expected. Use the following command for details: \n diff %s %s" % (
                self._title,
                expFile,
                outCueFile)

        self.assertEqual(res, exp, s)



#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_01(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '01 CueCreator with pregap and HTOA')
        self.setInputCueFile(   "01.cuecreator.cue")
        self.setExpectedFile(   "01.expected.cue")
        self.setPregapFile(     "00.Test.wav")




#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_01(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '01 CueCreator with pregap and HTOA')
        self.setInputCueFile(   "01.cuecreator.cue")
        self.setExpectedFile(   "01.expected.cue")
        self.setPregapFile(     "00.Test.wav")



#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_02(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '02 CueCreator w/o pregap, w/o HTOA')
        self.setInputCueFile(   "02.cuecreator.cue")
        self.setExpectedFile(   "02.expected.cue")



#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_03(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '03 CueCreator with pregap, w/o HTOA')
        self.setInputCueFile(   "03.cuecreator.cue")
        self.setExpectedFile(   "03.expected.cue")



#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_04(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '04 All tags')
        self.setInputCueFile(   "04.alltags.cue")
        self.setExpectedFile(   "04.alltags_expected.cue")


#*******************************************************************
#
#*******************************************************************
class cueCreatorTest_05(cueCreatorTest2):
    def setUp(self):
        cueCreatorTest2.setUp(self)
        self.setTitle(          '05 Cue w/o tags + tags form the separate file')
        self.setInputCueFile(   "05.cuecreator.cue")
        self.setExpectedFile(   "05.expected.cue")

        tracks = TrackSet()
        performer = "Artist"
        album = "Album"
        songs = [
            "Song01",
            "Song02",
            "Song03",
            "Song04"
        ]

        for song in songs:
            track = tracks.newTrack()
            track.setArtist("Artist")
            track.setAlbum("Album")
            track.setTitle(song)
            track.setGenre("Genre")
            track.setYear(2013)

        tracks.setDiscId('123456789')

        self._disc.addTrackSet(tracks)
        tracks.activate()

class TestSequenceFunctions(unittest.TestCase):

   #****************************************************************
   #
   #****************************************************************
    def _doTest_Track_expandPattern(self, title, pattern, expected, tokens):


        t = track.Track(None)
        res = t.expandPattern(pattern, tokens, False)
        self.assertEqual(res, expected, "%s\n  pattern:  %s\n  expected: %s\n  result:   %s" % (title, pattern, expected, res))


   #****************************************************************
   #
   #****************************************************************
    def test_Track_expandPattern(self):

        #res = self._expandPattern("%A", tokens)
        #self.assertEqual(res, "QQ" )

        tokens = {
            'N': "04",
            'n': "11",
            'A': 'Album',
            't': 'Song01',
            'a': 'Artist',
            'g': 'Genre',
            'y': "2013"
        }

        self._doTest_Track_expandPattern(
            "Default pttern",
            "%a/%y - %A/%n - %t",
            "Artist/2013 - Album/11 - Song01",
            tokens)

        self._doTest_Track_expandPattern(
            "Witout percents",
            "N/n/A/a/t/y/g",
            "N/n/A/a/t/y/g",
            tokens)

        self._doTest_Track_expandPattern(
            "Single",
            "/%%/%Q/%N/%n/%A/%a/%t/%y/%g/%%",
            "/%/%Q/04/11/Album/Artist/Song01/2013/Genre/%",
            tokens)

        self._doTest_Track_expandPattern(
            "Double",
            "%%Q/%%N/%%n/%%A/%%a/%%t/%%y/%%g",
            "%Q/%N/%n/%A/%a/%t/%y/%g",
            tokens)

        self._doTest_Track_expandPattern(
            "Tripple",
            "%%%Q/%%%N/%%%n/%%%A/%%%a/%%%t/%%%y/%%%g/%%%",
            "%%Q/%04/%11/%Album/%Artist/%Song01/%2013/%Genre/%%",
            tokens)

        tokens = {
            'N': "04",
            'n': "11",
            'A': '',
            't': 'Song01',
            'a': 'Artist',
            'g': '',
            'y': "2013"
        }

        self._doTest_Track_expandPattern(
            "Optional tokens",
            "{}/{Text}/{%n}/{%n Text}/{%A}/{%A Text}",
            "{}/{Text}/11/11 Text//",
            tokens)

        self._doTest_Track_expandPattern(
            "Optional tokens, w/o close",
            "Test{Text/{%n}/{%n Text}/{%A}/{%A Text}",
            "Test{Text/11/11 Text//",
            tokens)

        self._doTest_Track_expandPattern(
            "Optional tokens, w/o open ",
            "Text}/{%n}/{%n Text}/{%A}/{%A Text}",
            "Text}/11/11 Text//",
            tokens)

   #****************************************************************
   #
   #****************************************************************
    def doTestTrackIndexSub(self, idx1, idx2, expected):
        _idx1 = track.TrackIndex(idx1)
        _idx2 = track.TrackIndex(idx2)
        self.assertEqual((_idx1 - _idx2).asString(),  QString(expected))


   #****************************************************************
   #
   #****************************************************************
    def test_TrackIndex(self):
        idx = track.TrackIndex()
        self.assertEqual(idx.asString(),  QString("00:00:00"))

        idx = track.TrackIndex("12:34:56")
        self.assertEqual(idx.asString(),  QString("12:34:56"))

        self.doTestTrackIndexSub("12:34:56",
                                 "11:34:56",
                                 "01:00:00")

        self.doTestTrackIndexSub("12:11:01",
                                 "10:34:70",
                                 "01:36:06")

   #****************************************************************
   #
   #****************************************************************
    def dataDir(self):
        return os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + "/data/"




   #****************************************************************
   #
   #****************************************************************
    def doTest_CueCreator(self, title, inputCueFile, expectedCueFile, pregap):
        disc = Disc()
        tracks = trackset.CueTrackSet(self.dataDir() + inputCueFile)
        disc.addTrackSet(tracks)
        tracks.activate()

        outCueFile = "/tmp/cueCreator_out.cue"

        cue = cuecreator.CueCreator(tracks)
        cue.setPregapFileName(pregap)
        cue.write(outCueFile)

        res = open(outCueFile, 'r').read()
        expectedFile = self.prepareExpectedCUE(self.dataDir() + expectedCueFile)
        expected = open(expectedFile, 'r').read()
        s = "%s\nThe result is different from the expected. Use the following command for details: \n diff %s %s" % (
                title,
                expectedFile,
                outCueFile)

        self.assertEqual(res, expected, s)
        #self.assertEqual(res, expected, "%s\nexpected .....................\n%s\n\nresult ......................\n%s" % (title, expected, res))



#*******************************************************************
#
#*******************************************************************
if __name__ == '__main__':
    settings.settings.setValue('OutFiles/Pattern', '%a/%y - %A/%n - %t')
    settings.settings.setValue('OutFiles/Format',  'WAV')

    unittest.main()

